import datetime
from abc import ABCMeta, abstractmethod
from sqlalchemy.orm import Session
from docker import DockerClient
from app.controller.model.storage import GetStorageStatusRes, GetStorageStatusItem, GetStorageStatusSum
from app.dao.storage import get_storage, get_storage_count
from app.docker import Client


class StorageStatuser(metaclass=ABCMeta):
    @abstractmethod
    def status(self) -> GetStorageStatusRes:
        pass


class StorageStatuserImpl(StorageStatuser):
    db: Session
    client: DockerClient
    ItemHDFSitem: int
    ItemHDFScount: int
    ItemHBaseitem: int
    ItemHBasecount: int
    ItemMysqlitem: int
    ItemMysqlcount: int
    total: int
    today: int

    def __init__(self, db: Session,  client: DockerClient) -> None:
        super().__init__()
        self.db = db
        self.client = client
        self.ItemHDFScount = 0
        self.ItemHBasecount = 0
        self.ItemMysqlcount = 0
        self.total = 0
        self.today = 0

    def _get_service_form_db(self):
        return get_storage(self.db)

    def _get_service_num_form_db(self):
        return get_storage_count(self.db)

    def _get_time_by_service_id(self, id):
        services = self.client.services.list(filters={'id': id})
        if len(services) == 0:
            return None
        service = services[0]
        tasks = service.tasks()
        time = ''

        for task in tasks:
            if task['Status']['State'] == 'running':
                time = task['CreatedAt']
                break

        time = time.split('.')[0]

        time = time.split('T')[0]

        return time

    def _service_is_today(self, time):
        now = datetime.datetime.now()
        td = now.strftime("%Y-%m-%d")
        if td == time:
            return True
        else:
            return False

    def status(self) -> GetStorageStatusRes:
        storages = self._get_service_form_db()
        count = self._get_service_num_form_db()

        items = []
        for storage in storages:
            time = self._get_time_by_service_id(storage.service_id)
            if time is None:
                continue

            self.total += 1

            if self._service_is_today(time):
                self.today += 1
            if storage.type == 1:
                self.ItemHDFScount += 1
            elif storage.type == 2:
                self.ItemHBasecount += 1
            elif storage.type == 3:
                self.ItemMysqlcount += 1

        items.append(GetStorageStatusItem(item=1, count=self.ItemHDFScount))
        items.append(GetStorageStatusItem(item=2, count=self.ItemHBasecount))
        items.append(GetStorageStatusItem(item=3, count=self.ItemMysqlcount))

        return GetStorageStatusRes(sum=GetStorageStatusSum(total=self.total, today=self.today), items=items)


def get_storage_statuser(db: Session) -> StorageStatuser:
    return StorageStatuserImpl(db,  client=Client().client)
